using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.RuleEngine;

namespace BizTalk.BuildGenerator.Tasks.BRE
{
    /// <summary>
    /// Class containing methods for managing the BRE
    /// </summary>
    public class BREManager
    {
        private RuleSetDeploymentDriver _Driver;

        #region Ctor
        /// <summary>
        /// Ctor
        /// </summary>
        public BREManager()
        {
            _Driver = new RuleSetDeploymentDriver();
        }
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="databaseServer"></param>
        /// <param name="databaseName"></param>
        public BREManager(string databaseServer, string databaseName)
        {
            _Driver = new RuleSetDeploymentDriver(databaseServer, databaseName);
        }
        #endregion

        /// <summary>
        /// Imports and publishes a vocabulary or policy file
        /// </summary>
        /// <param name="filePath"></param>
        public void Import(string filePath)
        {           			
            this._Driver.ImportAndPublishFileRuleStore(filePath);			
        }
        /// <summary>
        /// Imports all vocabulary and policy files
        /// </summary>
        /// <param name="filePaths"></param>
        public void Import(List<string> filePaths)
        {
            filePaths.ForEach(new Action<string>(this.Import));
        }
        /// <summary>
        /// Exports all rules to a temporary location
        /// </summary>
        /// <param name="filePath"></param>
        public void ExportAll(string filePath)
        {
            RuleStore ruleStore = (SqlRuleStore)this._Driver.GetRuleStore();
            RuleStore exportRuleStore = new FileRuleStore(filePath);

            foreach(VocabularyInfo vocabularyInfo in ruleStore.GetVocabularies(RuleStore.Filter.All))
            {
                exportRuleStore.Add(ruleStore.GetVocabulary(vocabularyInfo));
            }
            foreach(RuleSetInfo ruleSetInfo in ruleStore.GetRuleSets(RuleStore.Filter.All))
            {
                exportRuleStore.Add(ruleStore.GetRuleSet(ruleSetInfo));
            }                
        }
        /// <summary>
        /// Removes all versions of a policy or vocabulary
        /// </summary>
        /// <param name="objectType">Should be RuleSetInfo or VocabularyInfo</param>
        /// <param name="name"></param>        
        public void Remove(RulesEngineObjectType objectType, string name)
        {
            RuleStore ruleStore = this._Driver.GetRuleStore();
            if (objectType == RulesEngineObjectType.VocabularyInfo)
            {
                foreach (VocabularyInfo vocabularyInfo in ruleStore.GetVocabularies(RuleStore.Filter.All))
                {
                    if (vocabularyInfo.Name == name)                    
                        ruleStore.Remove(vocabularyInfo);                    
                }
            }
            else if (objectType == RulesEngineObjectType.RuleSetInfo)
            {
                foreach (RuleSetInfo ruleSetInfo in ruleStore.GetRuleSets(RuleStore.Filter.All))
                {
                    if (ruleSetInfo.Name == name)
                        ruleStore.Remove(ruleSetInfo);
                }
            }
            else
                throw new ApplicationException("Invalid object type");
        }
        /// <summary>
        /// Removes a single entity from the rule store
        /// </summary>
        /// <param name="objectType">Should be RuleSetInfo or VocabularyInfo</param>
        /// <param name="name"></param>
        /// <param name="major"></param>
        /// <param name="minor"></param>
        public void Remove(RulesEngineObjectType objectType, string name, int major, int minor)
        {                        
            RuleStore sqlRuleStore = this._Driver.GetRuleStore();
            if (objectType == RulesEngineObjectType.VocabularyInfo)          
                sqlRuleStore.Remove(new VocabularyInfo(name, major, minor));            
            else if (objectType == RulesEngineObjectType.RuleSetInfo)            
                sqlRuleStore.Remove(new RuleSetInfo(name, major, minor));            
            else
                throw new ApplicationException("Invalid object type");            
        }
        /// <summary>
        /// Clears the business rules store
        /// </summary>
        public void RemoveAll()
        {
            RuleStore ruleStore = this._Driver.GetRuleStore();
            foreach (RuleSetInfo ruleSetInfo in ruleStore.GetRuleSets(RuleStore.Filter.All))
            {
                ruleStore.Remove(ruleSetInfo);
            }
            foreach(VocabularyInfo vocabulary in ruleStore.GetVocabularies(RuleStore.Filter.All))
            {
                ruleStore.Remove(vocabulary);
            }
        }
        /// <summary>
        /// Undeploys a RuleSet
        /// </summary>
        /// <param name="name"></param>
        /// <param name="major"></param>
        /// <param name="minor"></param>
        public void UndeployRuleSet(string name)
        {
            RuleStore ruleStore = this._Driver.GetRuleStore();            
            foreach (RuleSetInfo ruleSetInfo in ruleStore.GetRuleSets(RuleStore.Filter.All))
            {
                if (ruleSetInfo.Name == name)
                    this._Driver.Undeploy(ruleSetInfo);
            }                        
        }        
        /// <summary>
        /// Undeploys a RuleSet
        /// </summary>
        /// <param name="name"></param>
        /// <param name="major"></param>
        /// <param name="minor"></param>
        public void UndeployRuleSet(string name, int major, int minor)
        {            
            this._Driver.Undeploy(new RuleSetInfo(name, major, minor));            
        }
        /// <summary>
        /// Deploys a rule set
        /// </summary>
        /// <param name="name"></param>
        /// <param name="major"></param>
        /// <param name="minor"></param>
        public void DeployRuleSet(string name, int major, int minor)
        {            
            this._Driver.Deploy(new RuleSetInfo(name, major, minor));
        }
        /// <summary>
        /// Deploys all versions of a rules policy
        /// </summary>
        /// <param name="name"></param>
        public void DeployRuleSet(string name)
        {
            RuleStore ruleStore = this._Driver.GetRuleStore();
            foreach (RuleSetInfo ruleSetInfo in ruleStore.GetRuleSets(RuleStore.Filter.All))
            {
                if(ruleSetInfo.Name == name)
                    DeployRuleSet(ruleSetInfo.Name, ruleSetInfo.MajorRevision, ruleSetInfo.MinorRevision);
            } 
        }
    }
    /// <summary>
    /// Type of object to be removed from the rules engine
    /// </summary>
    public enum RulesEngineObjectType
    {
        VocabularyInfo,
        RuleSetInfo
    }
}

